import watchSizeForBrowsersOtherThanIE9 from "watch-size";
import { removeFromArray } from "./removeFromArray";

let intervalId;
const registered = [];
const INTERVAL_DURATION = 100;

function run() {
  intervalId = setInterval(() => {
    registered.forEach(test);
  }, INTERVAL_DURATION);
}

function stop() {
  clearInterval(intervalId);
  intervalId = null;
}

function test(item) {
  const { $el, listener, lastWidth, lastHeight } = item;
  const width = $el.offsetWidth;
  const height = $el.offsetHeight;

  if (lastWidth !== width || lastHeight !== height) {
    item.lastWidth = width;
    item.lastHeight = height;

    listener({ width, height });
  }
}

function watchSizeForIE9($el, listener) {
  const item = {
    $el,
    listener,
    lastWidth: null,
    lastHeight: null
  };
  const unwatch = () => {
    removeFromArray(registered, item);
    if (!registered.length) stop();
  };

  registered.push(item);
  // The original watch-size will call the listener on initialization.
  // Keep the same behavior here.
  test(item);
  run();

  return unwatch;
}

export function watchSize($el, listener) {
  // See: https://stackoverflow.com/a/31293352
  const isIE9 = document.documentMode === 9;
  // watch-size will call the listener on initialization.
  // Disable this behavior with a lock to achieve a clearer code logic.
  let locked = true;
  const wrappedListener = (...args) => locked || listener(...args);
  const implementation = isIE9 ? watchSizeForIE9 : watchSizeForBrowsersOtherThanIE9;
  const removeSizeWatcher = implementation($el, wrappedListener);
  locked = false; // unlock after initialization

  return removeSizeWatcher;
}
